// vim: set expandtab tabstop=4 shiftwidth=4 fdm=marker:


#include "clib_tpl.h"


/* {{{ clib_tpl::clib_tpl() */
/**
 * Initial clib_tpl class.
 */
clib_tpl::clib_tpl( void )
{
    mstr_filetext = "";
    mstr_block    = "";

    memset( &mst_lock, 0, sizeof(mst_lock) );
    pthread_mutex_init( &mst_lock, NULL );
}
/* }}} */


/* {{{ clib_tpl::~clib_tpl() */
/**
 * Destory clib_tpl class.
 */
clib_tpl::~clib_tpl( void )
{
    pthread_mutex_destroy( &mst_lock );
}
/* }}} */


/* {{{ clib_tpl::read_file() */
/**
 * Read file content.
 *
 * @param   as_filename     Template filename.
 * @return                  0: succ,!=0: fail.
 */
int clib_tpl::read_file( char *as_filename )
{
    char s_text[CLIB_TPL_SLEN_TEXT] = { 0 };
    FILE *fp = NULL;

    if ( as_filename == NULL || strlen(as_filename) <= 0 ) {
        return( CLIB_TPL_ERR_PARA );
    } // if

    fp = fopen( as_filename, "r" );
    if ( fp == NULL ) return( CLIB_TPL_ERR_READ );

    if ( fread(s_text, sizeof(s_text)-1, 1, fp) < 0 ) {
        fclose( fp );
        return( CLIB_TPL_ERR_READ );
    } // if

    fclose( fp );
    mstr_filetext = s_text;
    return( CLIB_TPL_OK );
}
/* }}} */


/* {{{ clib_tpl::set_block() */
/**
 * Set block.
 *
 * @param   as_beg      Block begin text.
 * @param   as_end      Block end text.
 * @return              0: succ,!=0: fail.
 */
int clib_tpl::set_block( char *as_beg, char *as_end )
{
    int  i_ret     = 0,
         i_idx_beg = 0,
         i_idx_end = 0;

    if ( as_beg == NULL || strlen(as_beg) <= 0 ) {
        i_idx_beg = 0;
    } else {
        i_idx_beg = mstr_filetext.find( as_beg );
        if ( i_idx_beg >= 0 ) i_idx_beg += strlen( as_beg );
    } // if
    if ( as_end == NULL || strlen(as_end) <= 0 ) {
        i_idx_end = mstr_filetext.length();
    } else {
        i_idx_end = mstr_filetext.find( as_end );
    } // if

    if ( i_idx_beg < 0 || i_idx_end < 0 || i_idx_beg > i_idx_end ) {
        mstr_block = mstr_filetext;
        i_ret      = CLIB_TPL_ERR_FIND;
    } else {
        mstr_block = mstr_filetext.substr( i_idx_beg, i_idx_end - i_idx_beg );
        i_ret      = CLIB_TPL_OK;
    } // if
    return( i_ret );
}
/* }}} */


/* {{{ clib_tpl::set_key() */
/**
 * Set key value.
 *
 * @param   as_key      Key name.
 * @param   as_val      Value.
 * @return              0: succ,!=0: fail.
 */
int clib_tpl::set_key( char *as_key, char *as_val )
{
    std::map<std::string, std::string>::iterator    iter;

    if ( as_key == NULL
                || as_val == NULL
                || strlen(as_key) <= 0
                || strlen(as_val) <  0 ) {
        return( CLIB_TPL_ERR_PARA );
    } // if

    iter = mmap_key.find( as_key );
    if ( iter != mmap_key.end() ) {
        mmap_key.erase( iter );
    } // if
    mmap_key.insert( std::map<std::string, std::string>::value_type(as_key, as_val) );
    return( CLIB_TPL_OK );
}
/* }}} */


/* {{{ clib_tpl::reset_key() */
/**
 * Reset key-value map.
 */
int clib_tpl::reset_key( void )
{
    mmap_key.clear();
    return( CLIB_TPL_OK );
}
/* }}} */


/* {{{ clib_tpl::get_block() */
/**
 * Put out block & replace key as value.
 *
 * @retval  string      Replaced block text.
 */
std::string clib_tpl::get_block( void )
{
    std::map<std::string, std::string>::iterator    iter;
    std::string str_src;
    //std::string str_des;
    int     i_index = 0;

    str_src = mstr_block;
    //iter = mmap_key.begin();

    for ( iter = mmap_key.begin(); iter != mmap_key.end(); iter++ ) {
        //printf( "%s : %s\n", (*iter).first.c_str(), (*iter).second.c_str() );
        //printf( "# %d\n", iter != mmap_key.end() );
    
        //i_index = str_src.find( (*iter).first );
        while ( ( i_index = str_src.find((*iter).first) ) >= 0 ) {
/*
            str_des = str_src.substr( 0, i_index )
                        + (*iter).second
                        + str_src.substr( i_index + (*iter).first.length() );
            str_src = str_des;
*/
            str_src.replace( i_index, (*iter).first.length(), (*iter).second );
        } // if
    } // for

    return( str_src );
}
/* }}} */


/* {{{ clib_tpl::put_block() */
/**
 * Printf block & replace key as value.
 *
 * @return              0: succ,!=0: fail.
 */
int clib_tpl::put_block( void )
{
    printf( "%s", (this->get_block()).c_str() );
    return( CLIB_TPL_OK );
}
/* }}} */

